<!-- 
在 Vue 3 中， `toRefs`  是一个用于将响应式对象的属性转换为响应式引用（ref）的实用工具。它通常与组合 API 一起使用，特别是在  `setup`  函数中，以便在组件中更灵活地使用响应式数据。以下是关于  `toRefs`  的说明总结：
  1. 基本概念
  -  `toRefs`  函数将一个响应式对象的每个属性转换为单独的  `ref` ，这样可以在模板中直接使用这些属性，同时保持响应性。
  - 通过将响应式对象的属性转换为  `ref` ，可以避免解构赋值时失去响应性的问题。
  2. 使用场景
  当你在  `setup`  函数中使用响应式对象（如  `reactive`  创建的对象）时，如果直接解构这个对象的属性，Vue 会失去对这些属性的响应性。使用  `toRefs`  可以解决这个问题。

  3. 使用示例
   创建响应式对象
  import { reactive, toRefs } from 'vue';

  export default {
    setup() {
      const state = reactive({
        count: 0,
        message: 'Hello Vue 3!'
      });

      // 使用 toRefs 将响应式对象的属性转换为 ref
      return {
        ...toRefs(state)
      };
    }
  };
  4. 在模板中使用
  在模板中，可以直接使用  `count`  和  `message` ，因为它们已经被转换为  `ref` 。
  vue
  <template>
    <div>
      <p>{{ message }}</p>
      <button @click="count++">Count: {{ count }}</button>
    </div>
  </template>
  5. 注意事项
  - 使用  `toRefs`  时，返回的每个属性都是一个  `ref` ，因此在使用它们时，可以直接在模板中访问，而不需要使用  `.value` 。
  - 如果不使用  `toRefs` ，直接解构响应式对象的属性，将会导致这些属性失去响应性。

  6. 总结
  `toRefs`  是 Vue 3 中一个非常有用的工具，能够有效地将响应式对象的属性转换为响应式引用。它帮助开发者在使用组合 API 时保持数据的响应性，避免解构赋值带来的问题。理解和掌握  `toRefs`  的使用，可以使得 Vue 3 组件的状态管理更加灵活和高效。 
-->
<template>
  <div>
    <div>info: {{ name }} - {{ age }} - {{ height }}</div>
    <p>objName: {{ objName }} - {{ heightObj }}</p>
    <button @click="handler">修改age</button>
    <button @click="height = 1.89">修改height</button>
  </div>
</template>

<script>
import { reactive, toRefs, toRef, onMounted } from 'vue'

export default {
  setup() {
    // 1. toRef： 将reactive对象中的某个属性转换为ref对象
    // 2. toRefs： 将reactive对象中的所有属性转换为ref对象
    const info = reactive({
      name: 'toRefs-name',
      age: 18,
      height: 1.88,
    })

    // reactive被解构后会变成普通的值, 失去响应式, 通过toRefs可以将其转换为ref重新获得响应式
    const { name, age } = toRefs(info)
    const height = toRef(info, 'height') // 将reactive对象中的height属性转换为ref对象

    /**
     * 注意：
     * 1. 针对于普通对象使用toRefs和toRef在定时器/生命周期钩子函数中，没有纯响应式修改的值，是不会触发响应式的，如果有纯响应式对象，则可以触发响应式。
     * 2. 普通对象使用toRefs和toRef在点击事件和setup中可以触发响应式。
     *
     */
    let obj = {
      name: 'toRef-name',
      age: 18,
      height: 1.88,
    }
    const heightObj = toRef(obj, 'height') // 将普通对象中的height属性转换为ref对象，有差异
    const { name: objName } = toRefs(obj) // 将普通对象中的height属性转换为ref对象，有差异

    // setTimeout(() => {
    //   // name.value = 'toRefs-name-new-value'
    //   objName.value += 'toRef-name-new'
    //   heightObj.value++
    // }, 2000)

    // onMounted(() => {
    //   name.value = 'toRefs-name-new-value'
    //   objName.value += 'toRef-name-new'
    //   heightObj.value++
    // })

    console.log(this, window)

    function handler() {
      age.value++
      objName.value += 'toRef-name-new'
    }

    return {
      name,
      age,
      height,
      objName,
      handler,
      heightObj,
    }
  },
}
</script>

<style scoped></style>
